#include "Sock.hh"
#include <functional>
#include <vector>

namespace tom_tcpSever
{
    using func_t = std::function<void(int)>;
    class TcpServer;
    class ThreadData
    {
    public:
        ThreadData(int sock, TcpServer *server)
            : sock_(sock), server_(server)
        {
        }
        ~ThreadData() {}

    public:
        int sock_;
        TcpServer *server_;
    };

    class TcpServer
    {
    private:
        static void *ThreadRoutine(void *args)
        {
            pthread_detach(pthread_self());
            ThreadData *td = static_cast<ThreadData *>(args);
            td->server_->Execute(td->sock_);
            close(td->sock_);
            delete td;
            return nullptr;

        }

    public:
        TcpServer(const uint16_t &port, const string &ip = "0.0.0.0")
        {
            _listenSock = _sock.Socket();
            _sock.Bind(_listenSock, ip, port);
            _sock.Listen(_listenSock);
        }
        void BindHandler(func_t func)
        {
            _func.push_back(func);
        }
        void Execute(int sock)
        {
            for (auto &f : _func) // 妙啊
            {
                f(sock);
            }
        }
        void Start()
        {
            while (true)
            {
                string clientIp;
                uint16_t clientPort;
                int sock = _sock.Accept(_listenSock, &clientIp, &clientPort);
                if (sock == -1)
                    continue;
                cout << "creat new link success:" << sock << endl;
                // thread tid(ThreadRoutine);
                pthread_t tid;
                unique_ptr<ThreadData> td(new ThreadData(sock, this));
                pthread_create(&tid, nullptr, ThreadRoutine, nullptr);
            }
        }

    private:
        int _listenSock;
        Sock _sock;
        vector<func_t> _func;
    };
}
